#ifndef CLINT_H
#define CLINT_H

#include <stdint.h>

// CLINT（Core Local Interrupt Controller）物理地址映射（QEMU virt平台）
#define CLINT_BASE_ADDR 0x2000000UL  // CLINT起始地址
#define CLINT_MTIMECMP_OFFSET 0x4000  // 定时器比较寄存器偏移（按HART分组，每组8字节）
#define CLINT_MTIME_OFFSET 0xBFF8     // 全局定时器计数器偏移（64位，所有HART共享）

// 计算CLINT寄存器地址的宏
#define CLINT_MTIMECMP(hart) (CLINT_BASE_ADDR + CLINT_MTIMECMP_OFFSET + 8 * (hart))
#define CLINT_MTIME          (CLINT_BASE_ADDR + CLINT_MTIME_OFFSET)


// 初始化CLINT：设置首次定时器中断触发时间（1ms后）
void clint_init(void);

// 更新定时器比较值，设置下一次中断触发时间（周期性中断用）
void clint_set_next_tick(uint32_t hart);

// 读取当前全局时间计数器的值
static inline uint64_t clint_get_mtime(void) {
    return *(volatile uint64_t*)CLINT_MTIME;
}

// 设置指定HART的定时器比较值（直接操作硬件寄存器）
static inline void clint_set_mtimecmp(uint32_t hart, uint64_t value) {
    *(volatile uint64_t*)CLINT_MTIMECMP(hart) = value;
}

#endif  // CLINT_H
